package com.xxx.video.commen.fragments;

import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ViewAnimator;

import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;


import com.xxx.video.R;
import com.xxx.video.commen.presenters.BasePresenter;
import com.xxx.video.commen.presenters.ICommonBaseView;

import org.greenrobot.eventbus.EventBus;

import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;

public abstract class BaseFragment<P extends BasePresenter> extends Fragment implements ICommonBaseView {
    /**
     * base view
     */
    public View mContextView;
    /**
     *
     */
    private ViewAnimator mViewAnimator;
    /**
     *
     */
    private Unbinder unbinder;
    /**
     *
     */
    private boolean isFragmentVisible;
    /**
     *
     */
    public boolean isFirstInit = false;
    /**
     *
     */
    private P presenter;
    /**
     * is first load
     */
    public boolean isFirst = true;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        initLayout(inflater, container);
        unbinder = ButterKnife.bind(this, mContextView);
        return mContextView;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            isFragmentVisible = true;
        }
        if (mContextView == null) {
            return;
        }
        //visible，and not load
        if (!isFirstInit && isFragmentVisible) {
            onFragmentVisibleChange(true);
            return;
        }
        //visible——>gone  load yet
        if (isFragmentVisible) {
            onFragmentVisibleChange(false);
            isFragmentVisible = false;
        }
    }

    /**
     * init layout
     *
     * @param inflater  inflater
     * @param container rootView
     */
    public void initLayout(LayoutInflater inflater, ViewGroup container) {
        if (isUseMultiLayerLayout()) {
            mContextView = inflater.inflate(R.layout.activity_base, container, false);
            mViewAnimator = mContextView.findViewById(R.id.activity_base);
            /*
             * loading view
             */
            inflater.inflate(getLoadingLayout(), mViewAnimator, true);
            /*
             * content view
             */
            inflater.inflate(getContentLayout(), mViewAnimator, true);
            /*
             * empty view
             */
            inflater.inflate(getNoDataLayout(), mViewAnimator, true);
            /*
             * load data error
             */
            inflater.inflate(getErrorLayout(), mViewAnimator, true);
        } else {
            mContextView = inflater.inflate(getContentLayout(), container, false);
        }
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        /*
         * init toolbar
         */
        initToolbarData();
        /*
         * bind presenter
         */
        bindPresenter();
        /*
         * init data
         */
        initData(getArguments());
        //visible，but not load
        if (isFragmentVisible && !isFirstInit) {
            onFragmentVisibleChange(true);
        }
    }

    /**
     * when fragment's visible state changes will call this method
     * if the fragment first load，wait onCreateView method and it will call this method ，other call back same to t {@link #setUserVisibleHint(boolean)}
     * int this method  you can do some thing
     *
     * @param isVisible true  gone -> visible
     *                  false visible  -> gone
     */
    protected void onFragmentVisibleChange(boolean isVisible) {

    }

    @Override
    public void onResume() {
        super.onResume();
        if (isOpenEventBus()) {
            if (!EventBus.getDefault().isRegistered(this)) {
                EventBus.getDefault().register(this);
            }
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (isOpenEventBus()) {
            if (EventBus.getDefault().isRegistered(this)) {
                EventBus.getDefault().unregister(this);
            }
        }
        unBindPresenter();
        unbinder.unbind();
        isFirstInit = false;
        mContextView = null;
    }

    @OnClick({ R.id.tv_common_error_layout_refresh})
    public void onActionBarViewClicked(View view) {
        switch (view.getId()) {
            case R.id.tv_common_error_layout_refresh:
                showLayoutStatus(0);
                refreshData(getArguments());
                break;
            default:
                break;
        }
    }

    @Override
    public void initToolbarData() {

    }

    @Override
    public void intent2Activity(Class clazz) {
        Intent intent = new Intent(getContext(), clazz);
        getContext().startActivity(intent);
    }

    @Override
    public void intent2Activity(Class clazz, Bundle bundle) {
        Intent intent = new Intent(getContext(), clazz);
        intent.putExtras(bundle);
        getContext().startActivity(intent);
    }

    @Override
    public void intent2Activity(Class clazz, int requestCode) {
        Intent intent = new Intent(getContext(), clazz);
        startActivityForResult(intent, requestCode);
    }

    @Override
    public void intent2Activity(Class clazz, Bundle bundle, int requestCode) {
        Intent intent = new Intent(getContext(), clazz);
        intent.putExtras(bundle);
        startActivityForResult(intent, requestCode);
    }

    @Override
    public void showFragment(Fragment fragment) {
        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.show(fragment);
        transaction.commit();
    }

    @Override
    public void hideFragment(Fragment fragment) {
        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.hide(fragment);
        transaction.commit();
    }

    @Override
    public void addFragment(int containerViewId, Fragment fragment, @Nullable String tag) {
        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(containerViewId, fragment, tag);
        transaction.commit();
    }

    @Override
    public void replaceFragment(int containerViewId, Fragment fragment) {
        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(containerViewId, fragment);
        transaction.commit();
    }

    @Override
    public boolean isOpenEventBus() {
        return false;
    }

    @Override
    public boolean isUseMultiLayerLayout() {
        return true;
    }

    @Override
    public int getErrorLayout() {
        return R.layout.common_error_layout;
    }

    @Override
    public int getLoadingLayout() {
        return R.layout.common_loading_layout;
    }

    @Override
    public int getNoDataLayout() {
        return R.layout.common_no_data_layout;
    }


    @Override
    public void bindPresenter() {
        if (null == presenter) {
            presenter = createPresenter();
        }
    }

    @Override
    public void unBindPresenter() {
        if (null != getPresenter()) {
            getPresenter().unBindPresenter();
            presenter = null;
        }
    }

    /**
     * create a presenter
     *
     * @return presenter
     */
    protected P createPresenter() {
        return null;
    }

    /**
     * get a presenter
     *
     * @return presenter
     */
    protected P getPresenter() {
        return presenter;
    }

    @Override
    public void showLayoutStatus(int showState) {
        if (!isUseMultiLayerLayout()) {
            return;
        }
        if (mViewAnimator == null) {
            return;
        }
        int displayedChild = mViewAnimator.getDisplayedChild();
        if (displayedChild == showState) {
            return;
        }
        mViewAnimator.setDisplayedChild(showState);
    }
}
